home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / HardwareProjects / spartan.lha / NewSformat / NewSformat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-16  |  9.1 KB  |  428 lines

  1. /*   SFormat version 2.0 by Paul Harker....written in Manx C v3.6    */
  2. /*    Mike Lundberg added delay after select line is de-asserted, 
  3.         compileable on Lattice */
  4.        
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9.  
  10. typedef unsigned char byte;
  11.  
  12. byte RESET  = 128;        /*define CONTROL flags*/
  13. byte BUSY    = 64;
  14. byte REQUEST = 32;
  15. byte MSG     = 16;
  16. byte COMMAND  = 8;
  17. byte INPUT    = 4;
  18.  
  19. byte ACK     = 16;        /*define cmd flags*/
  20. byte PHASE    = 8;
  21. byte SELECT   = 4;
  22. byte BUS      = 1;
  23.  
  24.  
  25. byte *data;        /*pointer to SCSI data register*/
  26. byte *initCMD;        /*pointer to SCSI ICR register*/
  27. byte *targetCMD;         /*pointer to SCSI TCR register*/
  28. byte *control;        /*pointer to SCSI control register*/
  29. byte *status;        /*pointer to SCSI status register*/
  30.  
  31.  
  32. byte inbuff[100], outbuff[100], cmdbuff[10], statin, msg; /* SCSI IO storage */
  33.  
  34. unsigned int address, intrlv;
  35.  
  36. void main()
  37. {
  38.     void errorCHECK();
  39.     void readERROR();
  40.     void reZERO();
  41.     void unitRDY();
  42.     void modeSEL();
  43.     void doFORMAT();
  44.     void clearCMD();
  45.     void clearOUT();
  46.     void clearIN();
  47.     void goodmorning();
  48.     void scsi();
  49.     void doIO();
  50.     void waitREQ();
  51.     void doBASE();
  52.  
  53.  
  54.     int dummy;
  55.     int c;
  56.  
  57.                      /* define base offsets of registers*/ 
  58.  
  59.     data = 0x000001;
  60.     initCMD = 0x000003;
  61.     targetCMD = 0x000007;
  62.     control = 0x000009;
  63.     status = 0x00000B;
  64.  
  65.     printf("\n\n               New SFormat, with a delay after SEL \n");
  66.     printf("                          Spartan-SCSI Formatter\n");
  67.     printf("                            © 1991 Paul Harker\n");
  68.     printf("\n  This utility will perform a low-level format of the hard");
  69.     printf(" drive. ALL data\n  will be destroyed.\n\n  Continue? (Y/N) :");
  70.  
  71.  
  72.     c = getchar();            /* Change for Lattice */
  73.     c = toupper(c);
  74.     if(c != 'Y')
  75.        exit(200);
  76.  
  77. /*
  78.         if(toupper(getchar()) != 'Y')
  79.     {
  80.       printf("exiting program!\n");
  81.           exit(200);
  82.         }
  83. */
  84.     printf("\n   Base Address of interface :");
  85.       doBASE();
  86.  
  87.                       /*  Toss a Null  */
  88.     gets(dummy);
  89.  
  90.     printf("\n  SCSI address :");
  91.       address = getNumber(0,6);
  92. /*
  93.  
  94.     printf("  Interleave :");
  95.       intrlv = getNumber(1,27); 
  96.       intrlv = 2; */
  97.     printf("\n  Ready to format.\n\n  Continue? (Y/N) :");
  98.  
  99.     c = getchar();        /* Change for Lattice */
  100.     c = toupper(c);
  101.     if(c != 'Y')
  102.        exit(200);
  103. /*
  104.         if (toupper(getchar()) != 'Y')
  105.             exit(200);
  106. */
  107.      printf("  Zeroing Drive..........");
  108.      fflush(stdout);    
  109.      reZERO();
  110.      errorCHECK();
  111.  
  112.      printf("  Checking Drive Ready...");
  113.      fflush(stdout);
  114.      unitRDY();
  115.      errorCHECK();
  116.  
  117.  
  118.      printf("  Selecting Mode.........");
  119.      fflush(stdout);
  120.      modeSEL();
  121.      errorCHECK();
  122.  
  123.      printf("  Formatting.............");
  124.      fflush(stdout);
  125.      doFORMAT();
  126.      errorCHECK();
  127.      printf("\n Format Complete.\n");
  128.      Execute("wait 4",0,0);
  129. }
  130.  
  131. void errorCHECK()    /* Check Status Byte and Report Error Data */
  132. {
  133. int count;
  134.  
  135. if (statin)
  136.     {  
  137.     if (statin == 8)
  138.        printf("\n SCSI Device Busy Error\n");
  139.     else 
  140.        {
  141.        readERROR();
  142.        printf("\n Completion Status Error #%d:",statin);
  143.        for (count = 0;count < 27 ;count ++) 
  144.            if (inbuff[count])
  145.                printf("\n Sense Error Byte #%d: %d",count,inbuff[count]);
  146.        }
  147.     Execute("wait 4",0,0);
  148.     exit(700);
  149.     }
  150. printf("OK\n");
  151. }
  152.  
  153. void readERROR()   /* Request Sense Command */
  154. {
  155. clearCMD();
  156. clearIN();
  157. cmdbuff[0] = 3;
  158. cmdbuff[4] = 27;       /* Read all possible sense data */
  159. scsi();
  160. }
  161.  
  162. /*  
  163.    future stuff eh dude?
  164. clearBUFF(&buff,elements)    /  Clear Specified Buffer  /
  165. int elements;
  166. byte buff[elements];
  167. {
  168. int count;
  169.  
  170. while (count = 0; count < elements; count++)
  171.     buff[count] = 0;
  172. }
  173. */
  174.  
  175. getNumber(lower,upper)   /* get a number between -32k to 32k  */
  176.  
  177. int lower, upper;
  178. {
  179. char input[10];
  180. int test = 0xffff;
  181.  
  182. while((test > upper) || (test < lower)){
  183.       gets(input);
  184.         test = atoi(input);
  185.           if ((test > upper) || (test < lower))
  186.              printf("\n  Bad Entry. Please try again  :");
  187.       }
  188. return test;
  189. }
  190.  
  191.  
  192.  
  193. void reZERO()
  194. {
  195.     clearCMD();
  196.     cmdbuff[0] = 1;
  197.     scsi();
  198. }    
  199.  
  200.  
  201. void unitRDY()
  202. {
  203.     clearCMD();
  204.     scsi();
  205. }
  206.  
  207.  
  208. void modeSEL()
  209. {
  210.     clearCMD();
  211.     clearOUT();
  212.  
  213.     cmdbuff[0] = 21;
  214.     cmdbuff[4] = 12;  /* parameter list length */
  215.  
  216.     outbuff[3] = 8;
  217.     outbuff[10] = 2;  /* high byte of block size -512 bytes- */
  218.  
  219.     scsi();
  220. }
  221.  
  222.  
  223. void doFORMAT()
  224. {
  225.  
  226.     clearCMD();
  227.     clearOUT();
  228.  
  229.     cmdbuff[0] = 4;
  230.     cmdbuff[4] = (byte) intrlv;
  231.  
  232.     scsi();   
  233. }
  234.  
  235.  
  236.  
  237. void clearCMD()   /*   Clear command buffer   */
  238. {
  239. int count;
  240.  
  241.    for(count=0;count <= 10 ;count++)
  242.        cmdbuff[count] = 0;
  243.  
  244. }
  245.  
  246.  
  247. void clearOUT()      /*   Clear output buffer    */
  248. {
  249. int count;
  250.  
  251.   for(count=0;count <= 100;count++)
  252.        outbuff[count] = 0;
  253. }
  254.  
  255.  
  256. void clearIN()       /*   Clear Input Data Buffer    */
  257. {
  258. int count;
  259.  
  260.    for(count = 0;count < 100;count++)
  261.       inbuff[count] = 0;
  262. }
  263.  
  264. void goodmorning()    /*wake up the controller*/
  265. {
  266. byte initiator = 128, target = (1 << address);
  267. long count;
  268.         
  269.     *initCMD = 0;                            /*clear the controller chip*/
  270.     *(initCMD + 2) = 0;
  271.     *control = 0;
  272.  
  273.     for(count = 0; *control & BUSY; count++){  /*if bus is busy, wait*/
  274.        if (count >= 100000){                /*wait for bus*/
  275.            printf("\n  SCSI bus BUSY error.\n\n");   
  276.            Execute("wait 4",0,0);
  277.            exit(100);
  278.            }
  279.        }
  280.  
  281.     *data = initiator | target;                   /*load scsi addresses */
  282.     *initCMD |= BUS;                         /*assert bus*/
  283.  
  284.     for(count = 0;count <60;count++);        /*wait 2 * 45 nanoseconds*/
  285.  
  286.     *initCMD |= SELECT;                      /*assert select*/
  287.  
  288.     for(count = 0; !(*control & BUSY); count++){
  289.         if (count >= 100000){            /*wait for busy from controller*/
  290.            printf("\n  No response from SCSI address #%d.\n\n",address);   
  291.            Execute("wait 4",0,0);  
  292.            exit(100);
  293.            }
  294.         }
  295.     for(count = 0;count < 60;count++);
  296.     *initCMD &= ~SELECT;                     /*deassert select*/
  297.     for(count = 0;count < 60;count++);       /* mod by Mike Lundberg */
  298. }
  299.  
  300.  
  301.  
  302.  
  303. void scsi()          /* send Command and handle I/O */
  304. {
  305. byte dataout = 0, datain = 1, cmdout = 2,
  306.      instat = 3, msgin = 7;
  307.  
  308.     goodmorning();
  309.  
  310.     while (*control & BUSY){
  311.  
  312.        waitREQ();
  313.  
  314.        if (*control & COMMAND){                    /*cmd I/O?*/
  315.            if (*control & MSG){                    /*message?*/
  316.                if (*control & INPUT)              /*if message in*/
  317.                    doIO(msgin,&msg);             /*read it..msg out invalid*/
  318.            }
  319.  
  320.            else {                                 /*not msg..status or cmd*/
  321.                if (*control & INPUT)
  322.                    doIO(instat,&statin);          /*get status*/
  323.                else
  324.                    doIO(cmdout,cmdbuff);            /*send command*/
  325.           }
  326.        }
  327.  
  328.        else {                                    /*controller requests data I/O*/
  329.            if (*control & INPUT)                    /* input or output? */
  330.               doIO(datain,inbuff);                  /* input */
  331.            else
  332.               doIO(dataout,outbuff);                /* output */
  333.        }
  334.     }
  335. }
  336.  
  337.  
  338.  
  339. void doIO(mode,buffer)        /* Read-Send whatever the controller desires */
  340. byte mode, buffer[];
  341. {
  342. int index, count;
  343.  
  344.     *targetCMD = mode;                             /*what mode are we in*/
  345.  
  346.     for (index = 0;(*status & PHASE);index++){    /*while phase unchanged*/
  347.  
  348.          waitREQ();
  349.  
  350.          if (mode == 1 || mode == 3 || mode == 7)             /*if input*/
  351.             *(buffer + index) = *data;       /*get data*/
  352.  
  353.          else                                /*if output*/
  354.             *data = *(buffer + index);       /*write it*/
  355.  
  356.          *initCMD |= ACK;                  /*Perform ack*/
  357.  
  358.          while(*control & REQUEST);        /*wait for dropped req*/
  359.  
  360.          *initCMD &= ~ACK;                 /*drop ack*/
  361.  
  362.          for(count=0;count<4000;count++);  /*kill some time*/
  363.     }
  364.    *targetCMD = 0;
  365. }
  366.  
  367. void waitREQ()           /* Wait for REQ to be asserted */
  368. {
  369.     while(!(*control & REQUEST))
  370.         if(!(*control & BUSY) || !(*control & PHASE))
  371.             return;
  372. }
  373.             
  374. getADD(hex)
  375. char *hex;
  376. {
  377. int low, high, address;
  378.  
  379. high = unhex(*hex);
  380. low = unhex(*(hex+1));
  381. address = (high*16 + low);
  382. if (high < 0 || low < 0)
  383.     address = -1;
  384. return address;
  385. }
  386.  
  387. void doBASE()
  388. {
  389. char hex[20];
  390. int address = -1;
  391. unsigned long base;
  392.  
  393. while (address < 0)
  394.     {
  395.     scanf("%s",hex);
  396.     address = getADD(hex);
  397.     if (address < 0)
  398.         printf("\n  Bad Entry. Please try again  :");
  399.     }
  400. base = (address * 0x10000);
  401. data += base;          /*pointer to SCSI data register*/
  402. initCMD += base;       /*pointer to SCSI ICR register*/
  403. targetCMD += base;     /*pointer to SCSI TCR register*/
  404. control += base;       /*pointer to SCSI control register*/
  405. status += base;        /*pointer to SCSI status register*/
  406. }
  407.  
  408. unhex(ascii)
  409. char ascii;
  410. {
  411. int value;
  412. /*char tmp;*/
  413.  
  414. int c, tmp;
  415.  
  416. c = (int)ascii;
  417. tmp = toupper(c);
  418.  
  419. /*tmp = toupper(ascii);*/
  420. if (isalpha(tmp))
  421.     value = tmp-55;
  422. else if (isdigit(tmp))
  423.     value = tmp - 48;
  424. if (value > 15 || value < 0)
  425.     value = -1;
  426. return value;
  427. }
  428.